#include <Windows.h>
#include <assert.h>
#include "Utils.h"
#include <mmsystem.h>

namespace Utils
{

string getAppPathA()
{
    char szPathName[_MAX_PATH];
    memset(szPathName, 0, sizeof(szPathName));
    GetModuleFileNameA(NULL, szPathName, _MAX_PATH);

    string appName = string(szPathName);
	int pos = (int)appName.find_last_of("\\/");
    if(pos < 0)
    {
        return appName + "\\";
    }
    return appName.substr(0, pos+1);
}

wstring getAppPathW()
{
    wchar_t szPathName[_MAX_PATH];
    memset(szPathName, 0, sizeof(szPathName));
    GetModuleFileNameW(NULL, szPathName, _MAX_PATH);

    wstring appName = wstring(szPathName);
	int pos = (int)appName.find_last_of(L"\\/");
    if(pos < 0)
    {
        return appName + L"\\";
    }
    return appName.substr(0, pos+1);
}

string formatString(const char *format, ...)
{
	const int BUFFER_SIZE = 4096;
	char strbuf[BUFFER_SIZE];
    memset(strbuf, 0, sizeof(strbuf));

	va_list ap;
	va_start (ap, format);
	int result = ::vsnprintf_s(strbuf, BUFFER_SIZE, format, ap);
	va_end (ap);

	return string(strbuf, result);
}

wstring formatString(const wchar_t *format, ...)
{
	const int BUFFER_SIZE = 4096;
	wchar_t wstrbuf[BUFFER_SIZE];
    memset(wstrbuf, 0, sizeof(wstrbuf));

	va_list ap;
	va_start (ap, format);
	int result = ::vswprintf(wstrbuf, BUFFER_SIZE, format, ap);
	va_end (ap);
	return wstring(wstrbuf, result);
}

void msleep(int ms)
{
    Sleep(ms);
}

void longSleep(int ms, bool &isLoop)
{
    DWORD t1 = timeGetTime();
    while(isLoop)
    {
        msleep(10);
        DWORD t2 = timeGetTime();
        if((t2 - t1) >= ((DWORD)ms))
        {
            break ;
        }
    }
}

double calcAngle(double x1, double y1, double x2, double y2)
{
	double dAngle = 0.0;	
    if(((y2 <= y1) && (x2 >= x1)))
    {
/*
            x2.y2
        x1.y1
*/
		// 0~90
		dAngle = atan2(abs(y2 - y1), abs(x2 - x1))*180.0/3.1416;
    }
    else if(((y2 <= y1) && (x2 <= x1)))
    {
/*
            x2.y2
                x1.y1
*/
		// 90~180
		dAngle = atan2(abs(y2 - y1), -abs(x2 - x1))*180.0/3.1416;
    }
	else if(((y2 >= y1) && (x2 <= x1)))
	{
/*
            x1.y1
          x2.y2
*/
		// 180~270
		dAngle = atan2(abs(y2 - y1), abs(x2 - x1))*180.0/3.1416;
        dAngle = dAngle + 180.0;
	}
	else if((y2 >= y1) && (x2 >= x1))
	{
/*
            x1.y1
                x2.y2
*/
		// 270~360
		dAngle = atan2(abs(y2 - y1), -abs(x2 - x1))*180.0/3.1416;
        dAngle = dAngle + 180.0;
	}
    else
    {
        assert(false);
    }
	return dAngle;
}

double calcAngle(double x1, double y1, double x2, double y2, double x3, double y3, bool absAngle)
{
    return calcAngle(x2, y2, x1, y1, x2, y2, x3, y3, absAngle);
}

double calcAngle(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, bool absAngle)
{
	double dAngle1 = calcAngle(x1, y1, x2, y2);
	double dAngle2 = calcAngle(x3, y3, x4, y4);
	if(absAngle)
	{
		return abs((dAngle1 - dAngle2));
	}
	return (dAngle1 - dAngle2);
}

};
